<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 *  扩展模型
 *
 *	主要用于提供公用模型方法
 *
 * @author		winner <xianyunqing@gmail.com>
 * @link		http://code.google.com/p/xianyunqing/
 */
class Model_model extends CI_Model {

	protected $_options  =   array();

	/**
     * 构造函数
     *
     * @access public
     * @return void
     */
    public function __construct()
    {
		 parent::__construct();
	}

	/** 利用__call方法实现一些特殊的Model方法 */
	public function __call($method,$args) {
		if(in_array(strtolower($method),array('sql','field','table','where','join','order','limit','offset','page','having','group','lock','distinct'),true))
		{
			// 连贯操作的实现
			$this->_options[strtolower($method)] = $args[0];
			return $this;
		}
	}

	/** 获取模型 */
	public function getmodelname()
	{
        if(empty($this->_options['table']))
		{
            $this->model_name = substr(get_class($this),0,-6);
        }
		else
		{
			$this->model_name = $this->_options['table'];
		}
        return $this->model_name;
    }

   public function num($id = NULL)
   {
        $query = $this->parse_select();
		$count = $query->num_rows();
		$query->free_result();
        return $count;
   }

	/** 查询 单条信息
	 * andrew 2010-10-23 10:30 修改
	 * */

	public function find($id = NULL)
	{
        $this->db->limit(1);
        $query = $this->parse_select();
		$result_array = array();
        if($query->num_rows())
		{
			$result_array = $query->row_array();
		}
		$query->free_result();

		return $result_array;
    }

	/** 查询 列表信息 */
	public function findall($limit = NULL)
	{
		if(!empty($limit))
		{
			$this->_options['limit'] = $limit;
		}

		$query = $this->parse_select();
		$result = array();
		if ($query->num_rows() > 0)
        {
			$result = $query->result_array();
		}
		$query->free_result();
        return $result;
    }

	/** 查询 分页列表信息 */
	public function findpage($limit,$count = 0,$query = array())
	{
		$page = $this->input->get('p',TRUE);

		$page = (!empty($page) && is_numeric($page)) ? intval($page) : 1;
		$offset = ($page - 1) * $limit;

		$total_count = $count;

		//偏移量
		if($offset && is_numeric($offset))
		{
			$this->_options['offset'] = intval($offset);
		}

		$result = $this->findall($limit);

		if($result)
		{
			$pagination = '';
			if($total_count > $limit)
			{
				$this->load->library('dpagination');
				$this->dpagination->currentPage($page);
				$this->dpagination->items($total_count);
				$this->dpagination->limit($limit);
				$this->dpagination->adjacents(5);
				$this->dpagination->target(site_url($this->uri->uri_string().'?'.implode('&',$query)));
				$this->dpagination->parameterName('p');
				$this->dpagination->nextLabel('下一页');
				$this->dpagination->PrevLabel('上一页');
				$pagination = $this->dpagination->getOutput();
			}
			$output['count'] =	$total_count;
			$output['html']	 =	$pagination;
			$output['data']	 =	$result;
		}
		else
		{
			$output['count'] =	0;
			$output['html']	 =	'';
			$output['data']	 =	'';
		}
		return $output;
	}

	/** 操作 添加 */
	public function add($data = array())
	{
		$table = $this->parse_table();
       	$this->db->insert($table,$data);
		return ($this->db->affected_rows() ==1) ? $this->db->insert_id() : FALSE;
    }

	/** 操作 更新 */
	public function save($data=array(),$type = 'update')
	{
		$table = $this->parse_table();
        $where = $this->parse_where();
        if(!empty($where))
		{
			if($type == 'update')
			{
				$this->db->update($table,$data,$where);
			}
			else
			{
				$set = array();
				$this->db->where($where);
				foreach ($data as $col => $val) {
					//$set[] = $this->format_field($col).' = '.$this->format_value($val);
					$this->db->set($col,$val,FALSE);
				}
				//$set = implode(',', $set);
				//$this->db->query('UPDATE '.$table.' SET '.$set.' WHERE '.$where);
				$this->db->update($table);
			}
			return ($this->db->affected_rows() > 0)?TRUE:FALSE;

		}
		else
		{
			$this->add($data);
		}
	}



	/** 操作 删除 */
	function del()
	{
		$table = $this->parse_table();
        $where = $this->parse_where();
        if(!empty($where))
		{
			$this->db->delete($table,$where);
		}

		return ($this->db->affected_rows() > 0)?TRUE:FALSE;

	}

	/** 条件处理 - 查询 */
	public function parse_select()
	{
		//查询sql语句
		if (!empty($this->_options['sql']))
		{
            $sql = $this->_options['sql'];
			$this->db->query($sql);
            unset($this->_options['sql']);
        }
		else
		{
			//字段
            $field = '*';
            if (!empty($this->_options['field']))
			{
                if (is_array($this->_options['field']))
				{
                    $field = implode(',', $this->format_field($this->_options['field']));
                }
				else
				{
                    $field = $this->_options['field'];
                }
				$this->db->select($field);
                unset($this->_options['field']);
            }

			//表名
			$table = $this->parse_table();
			$this->db->from($table);
			//unset($table);


			if (!empty($this->_options['join']))
			{
				$this->parse_join();
				unset($this->_options['join']);
			}

			//条件
            $where = $this->parse_where();
            if (!empty($where))
			{
				$this->db->where($where);
				//unset($where);
			}

			//排序
            if (!empty($this->_options['order']))
			{
                $order = $this->_options['order'];
				$this->db->order_by($order);
                unset($this-> _options['order']);
            }

			//限制
            if (!empty($this->_options['limit'])&&is_numeric($this->_options['limit']))
			{
                $limit = $this->_options['limit'];
				$this->db->limit($limit);
                unset($this->_options['limit']);
            }

			//偏移量
			if (!empty($this->_options['offset'])&&is_numeric($this->_options['offset']))
			{
                $offset = $this->_options['offset'];
				$this->db->offset($offset);
                unset($this->_options['offset']);
            }

			//分组
            if(!empty( $this->_options['group' ]))
			{
                $group = $this->_options['group'];
				$this->db->group_by($group);
				unset($this->_options['group']);
            }

            if(!empty( $this->_options['having' ]))
			{
                $having = $this->_options['having'];
				$this->db->having($having);
				unset($this->_options['having']);
            }



        }
        return $this->db->get();
	}

	protected function parse_table()
	{
        if (!empty($this->_options['table']))
		{
            $table = $this->_options['table'];
        }
		else
		{
			$table = strtolower($this->getmodelname());
		}
        return $table;
    }

	//选择条件是字符还是数组
	protected function parse_where()
	{
        $where = '';
        if (!empty($this->_options['where']))
		{
            if (is_array($this->_options['where']))
			{
                $where = $this->format_where($this->_options['where']);
            }
            else
			{
                $where = $this->_options['where'];
            }
            unset($this->_options['where']);
        }
        return $where;
    }

	protected function parse_join()
	{
        $join = '';
        if (!empty($this->_options['join']))
		{
            if (is_array($this->_options['join']))
			{
				$array_join = $this->_options['join'];
				foreach($array_join as $key=>$val)
				{
					$join = $this->db->join($key, $val[0],$val[1]);

				}



            }
            unset($this->_options['join']);
        }
        return $join;
    }

    protected function parse_in($in_arr)
	{
        $in_str = "(";
        foreach($in_arr as $key=>$v) {
            $in_str .= "'".$v."'".",";
        }
        $in_str = rtrim($in_str,",");
        $in_str .= ")";
        return $in_str;
    }

	public function format_where($where)
	{

        if (is_array($where))
		{
            if (array_key_exists('_logic', $where))
			{
                $logic = strtoupper($where['_logic']);
                unset($where['_logic']);
            }
			else
			{
                $logic = 'AND';
            }
            foreach ($where as $key=>$term)
			{
				$keys = explode('.',$key);
                if(!is_array($term))
				{
					if(count($keys) == 2)
					{
                    	$term2 = is_string($term)?"(`{$keys[0]}`.`" . $keys[1]. "` = '" .$term . "')":"(`" . $keys[1]. "` = " .$term . ")";
					}
					else
					{
						$term2 = is_string($term)?"(`" . $key. "` = '" .$term . "')":"(`" . $key. "` = " .$term . ")";
					}
                }
				else
				{
                    switch(strtoupper($term[0]))
					{
                        case "IN":
                            $in = $this->parse_in($term[1]);
							if(count($keys) == 2)
							{
                            	$term2 = "(`{$keys[0]}`.`" . $keys[1]. "` IN " .$in . ")";
							}
							else
							{
								$term2 = "(`" . $key. "` IN " .$in . ")";
							}
                            break;
                        case "NOT IN":
                            $in = $this->parse_in($term[1]);
                            $term2 = "(`" . $key. "` NOT IN " .$in . ")";
                            break;
                        case "GT":
                            $term2 = "(`" . $key. "` > " .$term[1] . ")";
                            break;
                        case "LT":
                            $term2 = "(`" . $key. "` < " .$term[1] . ")";
                            break;
                        case "NEQ":
                            $term2 = "(`" . $key. "` != " .$term[1] . ")";
                            break;
                        case "LIKE":
							if(count($keys) == 2)
							{
								$term2 = "(`{$keys[0]}`.`" . $keys[1]. "` LIKE '" .$term[1] . "')";
							}
							else
							{
                           		$term2 = "(`" . $key. "` LIKE '" .$term[1] . "')";
							}
                            break;
                        case "BETWEEN":
                            $between = implode(" and ",$term[1]);
                            $term2 = "(`" . $key. "` BETWEEN " .$between . ")";
                            break;
                    }
                }

                $where2[] = $term2;
            }

            $where = implode(' ' . $logic . ' ', $where2);
        }
        return $where;
    }

	/** 获取最后执行sql语句 */
    public function lastsql()
	{
        return $this->db->last_query();
    }
	//获取字段
	public function field_data()
	{
		$table = strtolower($this->getmodelname());

		$fields = $this->db->field_data($table);
		foreach ($fields as $key => $field)
		{
			$arr_fields['fields'][$key] = $field->name;
			if($key == 0 and $field->primary_key == 1) $primary_key = $field->name;
		}
		$arr_fields['primary_key'] = $primary_key;
		return $arr_fields;
	}

	 //格式化 字段
	public function format_field($str = '')
	{
        if (is_array($str))
		{
            $str = array_map(array(__CLASS__, __METHOD__), $str);
            return $str;
        }
        $str && $str = "`{$str}`";
        return $str;
    }

	// 格式化 值
	public function format_value($str = '')
	{
        if (is_array($str))
		{
            $str = array_map(array(__CLASS__, __METHOD__), $str);
            return $str;
        }

        $str = addslashes($str);
		$str = str_replace(' ','',$str);

		if(is_array(explode('+',$str)) and count(explode('+',$str)) == 2)
		{
			$arr_str = explode('+',$str);
			$str = "`{$arr_str[0]}` + {$arr_str[1]}";
		}
		else
		{
        	$str = is_string($str)?"'{$str}'":"{$str}";
		}
        return $str;
    }

	//在view的foot执行SQL
	public function page_log($data)
	{
		$this->db->insert("page_log", $data);
		return true;
	}
        //增加用户浏览网页次数
        public function add_viewpages($uid){
            $this->db->set('viewnum','viewnum + 1',FALSE);
            $this->db->where(array('uid'=>$uid));
            $this->db->update('member_perfect');
        }
}

/* End of file model_mdl.php */
/* Location: ./application/models/model_mdl.php */